package yl.hs.bmipfull.service.laboratory.impl;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yl.hs.bmipfull.daos.laboratory.ITaskConfigDao;
import yl.hs.bmipfull.daos.laboratory.ITaskConfigDetailsDao;
import yl.hs.bmipfull.daos.production.IProductionTaskFertilizerDao;
import yl.hs.bmipfull.pojo.laboratory.ProductConfigDetailsEntity;
import yl.hs.bmipfull.pojo.laboratory.ProductConfigEntity;
import yl.hs.bmipfull.pojo.laboratory.TaskConfigDetailsEntity;
import yl.hs.bmipfull.pojo.laboratory.TaskConfigEntity;
import yl.hs.bmipfull.pojo.material.RawMaterialCateEntity;
import yl.hs.bmipfull.pojo.material.RawMaterialInfoEntity;
import yl.hs.bmipfull.pojo.production.ProductionTaskEntity;
import yl.hs.bmipfull.service.laboratory.IProductConfigService;
import yl.hs.bmipfull.service.laboratory.ITaskConfigBackupService;
import yl.hs.bmipfull.service.laboratory.ITaskConfigService;
import yl.hs.bmipfull.service.material.IPurchaseRequireService;
import yl.hs.bmipfull.service.material.IRawMaterialCateService;
import yl.hs.bmipfull.service.material.IRawMaterialInfoService;
import yl.hs.bmipfull.service.production.IProductionTaskFertilizerService;
import yl.hs.bmipfull.service.production.IProductionTaskService;
import yl.hs.bmipfull.utils.DataState;
import yl.hs.bmipfull.utils.Tl;
import yl.hs.bmipfull.utils.datastate.ActionType;
import yl.hs.bmipfull.utils.datastate.ProductConfigType;
import yl.hs.bmipfull.viewmodels.SubmitModel;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * TaskConfigServiceImpl
 *
 * @author 谢景广
 * @category
 * @date 2021-06-09
 */
@Service
public class TaskConfigServiceImpl extends LaboratoryBaseService implements ITaskConfigService {

    @Autowired
    ITaskConfigBackupService backupService;
    @Autowired
    ITaskConfigDao taskConfigDao;
    @Autowired
    ITaskConfigDetailsDao detailsDao;
    @Autowired
    IProductConfigService configService;
    @Autowired
    IProductionTaskService taskService;
    @Autowired
    IPurchaseRequireService requireService;
    @Autowired
    IRawMaterialCateService cateService;
    @Autowired
    IRawMaterialInfoService ramInfoService;
    @Autowired
    IProductionTaskFertilizerDao taskFertilizerDao;

    @Override
    public Map<String, Object> queryConfigByTaskSN(String taskSN) {
        Map<String, Object> result = new HashMap<>();
        var backList = backupService.queryBackByTaskSN(taskSN);
        List<RawMaterialCateEntity> cateList = cateService.querySelect();
        if (backList.size() > 0) {
            result.put("theoretical", backList.stream().filter(t -> t.getConfigType().equals(String.valueOf(ProductConfigType.Theoretical.code))).map(t -> {

                var cate = cateList.stream().filter(p -> p.getSn().equals(t.getRmCateSN())).findFirst();
                var cateName = "";
                if (cate.isPresent()) {
                    t.setRmCate(t.getRmCateSN());
                    cateName = cate.get().getCateName();
                }
                var item = t.toMap();
                item.put("rmCateName", cateName);
                return item;
            }).toList());
            result.put("production", backList.stream().filter(t -> t.getConfigType().equals(String.valueOf(ProductConfigType.Production.code))).map(t -> {
                var cate = cateList.stream().filter(p -> p.getSn().equals(t.getRmCateSN())).findFirst();
                var cateName = "";
                if (cate.isPresent()) {
                    t.setRmCate(t.getRmCateSN());
                    cateName = cate.get().getCateName();
                }
                var item = t.toMap();
                item.put("rmCateName", cateName);
                return item;
            }).toList());

        }
        var configs = taskConfigDao.queryConfigByTaskSN(taskSN);
        var details = detailsDao.queryByConfigSNList(configs.stream().map(t -> t.getSn()).toList());
        List<Map<String, Object>> configList = new ArrayList<>();
        for (var config : configs) {
            var item = config.toMap();
            item.put("details", details.stream().filter(t -> t.getTaskConfigSN().equals(config.getSn())).toList());
            configList.add(item);
        }
        result.put("configs", configList);


        if (result.size() > 0) {
            return result;
        }
        return null;
    }

    @Override
    public List<TaskConfigEntity> queryConfigEntityByTaskSN(String taskSn) {

        return taskConfigDao.queryConfigByTaskSN(taskSn);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveConfig(SubmitModel model) throws Exception {
        Map<String, Object> modelData = model.getData();
        String configSN = modelData.get("configSN").toString();
        String taskSn = model.getSn();
        ProductionTaskEntity taskEntity = taskService.findBySn(taskSn);
        //保存生产任务配比备份信息
        if (Boolean.parseBoolean(modelData.get("configChange").toString()) || !taskEntity.isConfigState()) {
            backupService.saveConfigBack(configSN, taskSn);
        }

        //获取基本配比信息
        ProductConfigEntity configEntity = configService.findBySn(configSN);
        List<Map<String, Object>> productLines = (List<Map<String, Object>>) modelData.get("productLines");
        //保生产任务配比信息
        try {
            Integer taskConfigResult = 0;

            taskConfigDao.deleteByTaskSn(taskSn);
            for (Map<String, Object> productLine : productLines) {
                String productionLineSN = productLine.get("productionLineSN").toString();
                TaskConfigEntity oldTaskConfig = taskConfigDao.queryConfigByTaskSNAndProductLine(taskSn, productionLineSN);

                taskConfigDao.deleteByTaskSnAndProductLine(taskSn, productionLineSN);
                String taskConfigSn = queryNewSN(TaskConfigEntity.class);
                TaskConfigEntity taskConfig = new TaskConfigEntity();
                taskConfig.setSn(taskConfigSn);
                taskConfig.setTaskSN(taskSn);
                taskConfig.setUseYear(configEntity.getUseYear());
                taskConfig.setUseQuarter(configEntity.getUseQuarter());
                taskConfig.setConfigSN(configSN);
                taskConfig.setConfigName(modelData.get("configName").toString());
                taskConfig.setMortarSN(modelData.get("mortarSN").toString());
                taskConfig.setConfigDisSn(modelData.get("configDisSn").toString());
                taskConfig.setProlineSN(productionLineSN);
                taskConfig.setWtgRatio(Tl.getBigDecimal(productLine.get("wtRatio")));
                taskConfig.setSandRatio(Tl.getBigDecimal(productLine.get("sandRatio")));
                taskConfig.setAdmixRatio(Tl.getBigDecimal(productLine.get("admixRatio")));
                taskConfig.setMixTime(Short.parseShort(productLine.get("mixTime") == null ? "0" : productLine.get("mixTime").toString()));
                taskConfig.setState(DataState.CREATED.code);
                taskConfig.setConfigType((short) 0);
                taskConfig.setDensity(BigDecimal.valueOf(0.00));
                taskConfig.setMortarName(modelData.get("mortarName").toString());
                taskConfig.setPYFieldValue();
                Integer insertTaskConfigResult = taskConfigDao.insertNew(taskConfig);
                taskConfigResult = +insertTaskConfigResult;
                if (insertTaskConfigResult > 0) {
                    if (Boolean.parseBoolean(modelData.get("configChange").toString())) {
                        writeLog(ActionType.CREATE, taskSn, "绑定生产任务配比", taskConfig.toJson(), TaskConfigEntity.class);
                    }
                    //保存生产任务配比明细信息
                    List<Map<String, Object>> taskConfigDetails = (List<Map<String, Object>>) productLine.get("details");
                    List<TaskConfigDetailsEntity> oldConfigDetails = new ArrayList<>();
                    if (oldTaskConfig != null && !Boolean.parseBoolean(modelData.get("configChange").toString()) && taskEntity.isConfigState()) {
                        String oldTaskConfigSn = oldTaskConfig.getSn();
                        oldConfigDetails = detailsDao.queryByTaskConfigSn(oldTaskConfigSn);
                        detailsDao.deleteByTaskConfigSn(oldTaskConfigSn);
                    }
                    for (Map<String, Object> taskConfigDetail : taskConfigDetails) {
                        TaskConfigDetailsEntity configDetail = new TaskConfigDetailsEntity();
                        configDetail.setSn(queryNewSN(TaskConfigDetailsEntity.class));
                        configDetail.setTaskConfigSN(taskConfigSn);
                        configDetail.setConfigSN(configSN);
                        RawMaterialInfoEntity rawInfo = ramInfoService.findBySn(taskConfigDetail.get("rmSN").toString());
                        configDetail.setRmSN(taskConfigDetail.get("rmSN").toString());
                        configDetail.setRmCate(taskConfigDetail.get("rmCateSN").toString());
                        configDetail.setRmName(taskConfigDetail.get("rmName").toString());
                        configDetail.setRmSpec(taskConfigDetail.get("rmSpec").toString());
                        configDetail.setBrand(rawInfo.getBrand());
                        configDetail.setStander(Tl.getBigDecimal(taskConfigDetail.get("standard")));
                        configDetail.setProduction(Tl.getBigDecimal(taskConfigDetail.get("prduction")));
                        configDetail.setWaterRatio(Tl.getBigDecimal(taskConfigDetail.get("water")));
                        configDetail.setPortName(taskConfigDetail.get("portName").toString());
                        configDetail.setWhSN(taskConfigDetail.get("whSN").toString());
                        configDetail.setWhName(taskConfigDetail.get("whName").toString());
                        configDetail.setPortCode(taskConfigDetail.get("portCode").toString());
                        configDetail.setOutScale(Tl.getBigDecimal(taskConfigDetail.get("outScale")));
                        configDetail.setSortCode(taskConfigDetail.get("sortCode").toString());
                        Integer insertDetailResult = detailsDao.insertNew(configDetail);
                        if (insertDetailResult > 0) {
                            if (!Boolean.parseBoolean(modelData.get("configChange").toString()) || taskEntity.isConfigState()) {
                                if (oldConfigDetails.size() > 0) {
                                    TaskConfigDetailsEntity taskConfigDetailsEntity = oldConfigDetails.stream().filter(t -> t.getPortCode().equals(configDetail.getPortCode())).findFirst().get();
                                    String detailsLog = productLine.get("plName") + configDetail.getRmName() + configDetail.getRmSpec() + ":";
                                    if (taskConfigDetailsEntity.getProduction().compareTo(configDetail.getProduction()) != 0) {
                                        detailsLog = detailsLog + "生产值" + taskConfigDetailsEntity.getProduction() + "->" + configDetail.getProduction();
                                        writeLog(ActionType.UPDATE, taskSn, detailsLog, configDetail.toJson(), TaskConfigDetailsEntity.class);
                                    }
                                    if (taskConfigDetailsEntity.getWaterRatio().compareTo(configDetail.getWaterRatio()) != 0) {
                                        detailsLog = detailsLog + "含水率" + taskConfigDetailsEntity.getWaterRatio() + "->" + configDetail.getWaterRatio();
                                        writeLog(ActionType.UPDATE, taskSn, detailsLog, configDetail.toJson(), TaskConfigDetailsEntity.class);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (taskConfigResult > 0) {
                if (!taskEntity.isConfigState()) {
                    //保存采购需求信息
                    requireService.createPurchaseRequire(taskSn);
                }
                taskEntity.setConfigState(true);
                taskConfigResult += taskService.updateTask(taskEntity);
            }
            return taskConfigResult;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    @Override
    public Integer HfsaveConfig(SubmitModel model) throws Exception {
        var result = 0;
        var map = model.getData();
        taskConfigDao.deleteByTaskSn(model.getSn());
        TaskConfigEntity taskconfig = new TaskConfigEntity();
        taskconfig.setTaskSN(model.getSn());
        taskconfig.setSn(queryNewSN(TaskConfigEntity.class));
        taskconfig.setState((short)2);
        result = taskConfigDao.insertNew(taskconfig);
        var list = (List<Map<String,Object>>)map.get("detail");
        for (var item : list) {
            TaskConfigDetailsEntity  taskConfigDetailsEntity = new TaskConfigDetailsEntity();
            taskConfigDetailsEntity.setTaskConfigSN(taskconfig.getSn());
            taskConfigDetailsEntity.setRmCate(item.get("rmCate").toString());
            taskConfigDetailsEntity.setRmCateName(item.get("rmCateName").toString());
            taskConfigDetailsEntity.setRmName(item.get("rmName").toString());
            taskConfigDetailsEntity.setRmSN(item.get("rmSN").toString());
            taskConfigDetailsEntity.setQuantity(new BigDecimal(item.get("quantity").toString()));
            taskConfigDetailsEntity.setProduction(new BigDecimal(item.get("production").toString()));
            taskConfigDetailsEntity.setQuantityMax(new BigDecimal(item.get("quantityMax").toString()));
            taskConfigDetailsEntity.setQuantityMin(new BigDecimal(item.get("quantityMin").toString()));
            taskConfigDetailsEntity.setRmSpec(item.get("rmSpec").toString());
            detailsDao.insertNew(taskConfigDetailsEntity);
        }
        var task =  taskFertilizerDao.findBySN(model.getSn());
        if(task!=null){
            task.setPlineName(map.get("plineName")==null?"":map.get("plineName").toString());
            task.setPlineSn(map.get("plineSn")==null?"":map.get("plineSn").toString());
            task.setPackImage(map.get("packImage")==null?"":map.get("packImage").toString());
            task.setCost(map.get("cost")==null? BigDecimal.valueOf(0) :new BigDecimal(map.get("cost").toString()));
            task.setPbstate((short) 1);
            task.setTaskPbSn(taskconfig.getSn());
            taskFertilizerDao.update(task);
        }
        return result;
    }

    @Override
    public TaskConfigEntity queryByTaskSnAndLineSn(String taskSn, String lineSn) {


        return taskConfigDao.queryConfigByTaskSNAndProductLine(taskSn,lineSn);
    }

}
